<?php

/**
 * STRING utf8 截断处理类
 * @package baseLib
 */

Class string_utf8
{
	function string_utf8()
	{
		/****/
	} 
	
	/**
	 * 处理截取中文字符串的操作
     * @return string
     * @param string $str 要处理的字符
	 * 		  string $start 开始位置
	 *        string $offset 偏移量
	 *        string $t_str 字符结果尾部增加的字符串，默认为空
	 *        boolen $ignore $start位置上如果是中文的某个字后半部分是否忽略该字符，默认true
	 */
	
	function substr_cn($str, $start, $offset, $t_str = '', $ignore = true)
	{
	 	$length  = strlen($str);
		if ($length <=  $offset && $start == 0)
		{
			return $str;
		}
		if ($start > $length)
		{
			return $str;
		}
		$r_str     = "";
		for ($i = $start; $i < ($start + $offset); $i++)
		{ 
			if (ord($str{$i}) > 127)
			{
				if ($i == $start)  //检测头一个字符的时候，是否需要忽略半个中文
				{
					$cut_length = string_utf8::is_cn_utf8_str($str, $i);
					
					if ( $cut_length!= -1)
					{
						if ($ignore && ($cut_length==2 || $cut_length==3 ))
						{
							$i=$i+(3-$cut_length);
							
							continue;
						}
						else
						{
							$i=$i - $cut_length + 1;
						
							$r_str .= $str{($i)}.$str{++$i}.$str{++$i};
							
						
						}
					}
					else
					{
						$r_str .= $str{$i};
					}
					
				}
				else
				{
					
					$r_str .= $str{$i}.$str{++$i}.$str{++$i};
				}
			}
			else
			{
				
				$r_str .= $str{$i};
				continue;
			}
			
		}
		
		return $r_str . $t_str;
		//return preg_replace("/(&)(#\d{5};)/e", "string::un_html_callback('\\1', '\\2')", $r_str . $t_str);
		
	}
	
	/**
	 * 截取处理字符串
	 * 规则同微博：中文2个字符，英文1个字符；截取末尾不足一个汉字的则舍弃
	 * 适用情况：UTF-8编码字符截取昵称、内容等
	 * 
	 * @param string  $str		需处理的字符串
	 * @param int     $len 		需截取的字符长度
	 * @param string  $suffix 	后缀，只有字符串被截取时才会被加后缀
	 * 
	 * add by zhanghuan at 2012/04/16
	 */
	function substr_utf8_cn_v2($str, $len, $suffix='')
	{
		if (strlen($str) <=  $len)
		{
			return $str;
		}
	
		$result_str = '';
		$orignal_str = $str;
		for($i=0;$i<$len;$i++)
		{
			$temp_str=substr($str,0,1);
			if(ord($temp_str) > 127)
			{
				if($i+1<$len)
				{
					$result_str .= substr($str,0,3);
					$str = substr($str,3);
				}
				$i++;
			}
			else
			{
				$result_str .= substr($str,0,1);
				$str=substr($str,1);
			}
		}
	
		if(strcmp($orignal_str, $result_str) > 0 && $suffix != '')
		{
			$result_str .= $suffix;
		}
		return $result_str;
	}
	
	/**
	 * 处理截取utf8下中文字符串的截断操作
     * @return string,中文当做1个长度处理
     * @param string $str 要处理的字符
     * 
     * PS：由于截取规则与微博不同（中文当做1个长度处理），适用时请注意规则条件(add by zhanghuan at 2012/04/16)
     * 
	 */
	function substr_utf8_cn($str,$len)
	{
		$length  = strlen($str);
		if ($length <=  $len)
		{
			return $str;
		}
		
		$new_str = array();
	    for($i=0;$i<$len;$i++)
	    {
	        $temp_str=substr($str,0,1);
	        if(ord($temp_str) > 127){
	          	if($i<$len)    
	       		{
		            $new_str[]=substr($str,0,3);
		            $str=substr($str,3);
	            }
	        }
		    else 
		    {
		        $new_str[]=substr($str,0,1);
		        $str=substr($str,1);
		     }
		}
	    
	    return join($new_str);

	}
	
	/**
	 * 判断字符某个位置是中文字符的左半部分还是右半部分，或不是中文
	 * 返回 0表示在中文3号位置，1表示在中文1号位置，2表示在2号位置,-1表示不是中文
     * @return int
	 * @param string $str 开始位置
	 * @param int $location 位置
	 */
	
	function is_cn_utf8_str($str, $location)
	{
		$cut_location=$location+1;
		$length = $location;
		if($location < 0 )return 1;
		if(ord($str{$length}) <= 127)return -1;
					
		 for($i = $length ;$i >=0; $i--)
		 {
		 	
		 	 if(ord($str{$i}) <= 127)
		 	 {
		 	 	$cut_location=$location-$i;
		 	 	break;
		 	 }
		 	
		 }
		 return $cut_location%3 ==0 ? 3 : $cut_location%3 ;
	}
	
	/**
	 * 截取HTML,并自动补全闭合
	 * @param $html
	 * @param $length
	 * @param $end
	 */
	function subHtml($html,$length) {
		 $result = '';
		 $tagStack = array();
		 $len = 0;
		
		 $contents = preg_split("~(<[^>]+?>)~si",$html, -1,PREG_SPLIT_NO_EMPTY| PREG_SPLIT_DELIM_CAPTURE);
		 foreach($contents as $tag)
		 {
			 if (trim($tag)=="")  continue;
			 if(preg_match("~<([a-z0-9]+)(.*?)/>~si",$tag)){
			 	$result .= $tag;
			 }else if(preg_match("~</([a-z0-9]+)[^/>]*?>~si",$tag,$match)){
				 if($tagStack[count($tagStack)-1] == $match[1]){
					 array_pop($tagStack);
					 $result .= $tag;
				 }
			 }else if(preg_match("~<([a-z0-9]+)[^/>]*?>~si",$tag,$match)){
				 array_push($tagStack,$match[1]);
				 $result .= $tag;
			 }else if(preg_match("~<!--.*?-->~si",$tag)){
			 	$result .= $tag;
			 }else{
				 if($len + self::mstrlen($tag) < $length){
				 	$result .= $tag;
				 	$len += self::mstrlen($tag);
				 }else {
				 	$str = self::msubstr($tag,0,$length-$len+1);
				 	$result .= $str;
				 	break;
				 }
			
			 }
		 }
		 while(!empty($tagStack)){
		 	$result .= '</'.array_pop($tagStack).'>';
		 }
		 return  $result;
	}
	
	/**
	 * 截取中文字符串
	 * @param $string 字符串
	 * @param $start 起始位
	 * @param $length 长度
	 * @param $charset  编码
	 * @param $dot 附加字串
	 */
	function msubstr($string, $start, $length,$dot='',$charset = 'UTF-8') {
		 $string = str_replace(array('&amp;', '&quot;', '&lt;', '&gt;','&nbsp;'), array('&', '"', '<', '>',' '), $string);
		 if(strlen($string) <= $length) {
		 	return $string;
		 }
		
		 if(strtolower($charset) == 'utf-8') {
		 	$n = $tn = $noc = 0;
			 while($n < strlen($string)) {
				 $t = ord($string[$n]);
				 if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
				 	$tn = 1; $n++;
				 } elseif(194 <= $t && $t <= 223) {
				 	$tn = 2; $n += 2;
				 } elseif(224 <= $t && $t <= 239) {
				 	$tn = 3; $n += 3;
				 } elseif(240 <= $t && $t <= 247) {
				 	$tn = 4; $n += 4;
				 } elseif(248 <= $t && $t <= 251) {
				 	$tn = 5; $n += 5;
				 } elseif($t == 252 || $t == 253) {
				 	$tn = 6; $n += 6;
				 } else {
				 	$n++;
				 }
				 $noc++;
				 if($noc >= $length) {
				 	break;
				 }
			 }
			 if($noc > $length) {
			 	$n -= $tn;
			 }
			 $strcut = substr($string, 0, $n);
		 } else {
			 for($i = 0; $i < $length; $i++) {
			 	$strcut .= ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i];
			 }
		 }
	
	 	return $strcut.$dot;
	}
	
	/**
	 * 取得字符串的长度，包括中英文。
	 */
	function mstrlen($str,$charset = 'UTF-8'){
		 if (function_exists('mb_substr')) {
		 	$length=mb_strlen($str,$charset);
		 } elseif (function_exists('iconv_substr')) {
		 	$length=iconv_strlen($str,$charset);
		 } else {
		 	preg_match_all("/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/", $str, $ar); 
		 	$length=count($ar[0]);
		 }
		 return $length;
	}
	
}
	





?>